package com.cash.channel.svc.service.common;

import com.cash.channel.api.model.user.IdInfoModel;
import com.cash.channel.svc.logic.ApplySubmitLogic;
import com.cash.channel.svc.logic.ImageLogic;
import com.cash.channel.svc.logic.ThirdCommonLogic;
import com.cash.channel.svc.model.FileInfoModel;
import com.cash.channel.svc.model.OrderInfoModel;
import com.cash.channel.svc.service.base.ApplySubmit;
import com.alibaba.fastjson.JSON;
import com.cash.channel.api.constant.Constant;
import com.cash.channel.api.exception.CashChannelException;
import com.cash.channel.api.model.ApiRequestModel;
import com.cash.channel.api.model.ApiResponseModel;
import com.cash.channel.api.model.enums.ApplySubmitStatusEnum;
import com.cash.channel.api.model.request.ApplySubmitRequest;
import com.cash.channel.api.model.response.ApplySubmitResponse;
import com.cash.channel.svc.logic.UserLogic;
import com.cash.channel.api.model.user.ThirdIdModel;
import com.cash.channel.svc.util.EmailUtils;
import com.cash.id.IDGen;
import com.cash.user.model.*;
import geex.fund.vcard.model.Response;
import geex.fund.vcard.model.SearchOcrInfoResponse;
import geex.fund.vcard.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.Date;
import java.util.Map;

@Slf4j
@Service(Constant.CHANNEL.COMMON+Constant.SERVICE.订单进件)
public class CommonApplySubmit implements ApplySubmit {

    @Autowired
    private ApplySubmitLogic applySubmitLogic;

    @Autowired
    private UserLogic userLogic;

    @Autowired
    private ImageLogic imageLogic;

    @Autowired
    private ThirdCommonLogic thirdCommonLogic;

    @Autowired
    private IDGen idGen;

    @Autowired
    private SearchService searchService;

    @Override
    public ApiResponseModel<ApplySubmitResponse> doApplySubmit(ApiRequestModel apiRequestModel) {
        try {
            ApplySubmitRequest applySubmitRequest = JSON.parseObject(apiRequestModel.getData(), ApplySubmitRequest.class);
            /*插入推送流水*/
            Integer flowId = applySubmitLogic.insertApplyPushFlow(apiRequestModel, applySubmitRequest);
             boolean flag =false;
             SearchOcrInfoResponse result =new SearchOcrInfoResponse();
            IdInfoModel idInfo =applySubmitRequest.getIdInfo();
            if ("beibei".equals(apiRequestModel.getChannel()) && (idInfo == null || StringUtils.isAnyBlank(idInfo.getVerifiedIdBackPath(),
                    idInfo.getVerifiedIdFrontPath(), idInfo.getVerifiedIdBirthday(), idInfo.getVerifiedIdRace(), idInfo.getVerifiedIdAddress(),
                    idInfo.getVerifiedIdGender(), idInfo.getVerifiedIdIssued(), idInfo.getVerifiedIdValidBegin(), idInfo.getVerifiedIdValidEnd()))) {
                Response<SearchOcrInfoResponse> searchOcrInfoResponse = searchService.searchOcrInfo(applySubmitRequest.getIdNo());
                log.info("消费贷花呗ocr信息：{}",searchOcrInfoResponse);
                 result = searchOcrInfoResponse.getResult();
                if (searchOcrInfoResponse.getSuccess()&&result!=null&&!StringUtils.isAnyBlank(result.getAcctName(), result.getAddress(), result.getFolk(),
                        result.getIdentifyNumber(), result.getAddress(), result.getOrgan(), result.getIdBeginDate(),
                        result.getIdExpiryDate(), result.getIdFrontUrl(), result.getIdBackUrl())) {
                    IdInfoModel idInfoModel =new IdInfoModel();
                    idInfoModel.setVerifiedIdNo(result.getIdentifyNumber());
                    idInfoModel.setVerifiedIdName(result.getAcctName());
                    idInfoModel.setVerifiedIdBirthday(result.getIdentifyNumber().substring(6,14));
                    idInfoModel.setVerifiedIdRace(result.getFolk());
                    idInfoModel.setVerifiedIdAddress(result.getAddress());
                    idInfoModel.setVerifiedIdIssued(result.getOrgan());
                    idInfoModel.setVerifiedIdValidBegin(result.getIdBeginDate());
                    idInfoModel.setVerifiedIdValidEnd(result.getIdExpiryDate());
                    applySubmitRequest.setIdInfo(idInfoModel);
                    flag =true;
                }
            }
            String frontPath = "";
            String backPath = "";
            if (flag) {
                frontPath = result.getIdFrontUrl();
                backPath = result.getIdBackUrl();
            } else {
                frontPath = imageLogic.uploadBase64Image(applySubmitRequest.getIdInfo().getVerifiedIdFrontPath());
                backPath = imageLogic.uploadBase64Image(applySubmitRequest.getIdInfo().getVerifiedIdBackPath());
            }

            /*初步插入id对应表*/
            ThirdIdModel thirdIdModel = new ThirdIdModel();
            thirdIdModel.setCApiId(String.valueOf(idGen.nextId()));
            thirdIdModel.setCThirdId(applySubmitRequest.getOrderNo());
            thirdIdModel.setCChannel(apiRequestModel.getChannel());
            thirdIdModel.setCMobile(applySubmitRequest.getMobile());
            thirdIdModel.setCThirdUserId(applySubmitRequest.getUserId());
            thirdCommonLogic.insertOrUpdateIdMapping(applySubmitRequest.getOrderNo(), apiRequestModel.getChannel(), thirdIdModel);

            /*生成新用户*/
            userLogic.registerChannelAccount(applySubmitRequest.getMobile(), apiRequestModel.getChannel());
            UserInfoModel userInfoModel = createUserInfoModelByRequest(applySubmitRequest);
            String uid = userLogic.saveUserInfoModel(userInfoModel);
            userInfoModel.setcUid(uid);
            userLogic.bindUUIDToAccount(uid, applySubmitRequest.getMobile());

            /*更新uid进id对应表*/
            thirdIdModel.setCUserUid(uid);
            thirdCommonLogic.insertOrUpdateIdMapping(applySubmitRequest.getOrderNo(), apiRequestModel.getChannel(), thirdIdModel);

            /*生成订单信息*/
            OrderInfoModel orderInfoModel = createOrderInfoModel(userInfoModel, applySubmitRequest, frontPath, backPath);

            /*插入ocr信息*/
            userLogic.insertUserIdVerified(orderInfoModel, applySubmitRequest, frontPath, backPath, apiRequestModel.getChannel());

            /*生成认证订单*/
            Map<String, Object> apiResult = userLogic.pushQcInfoToHaneda(orderInfoModel, apiRequestModel.getChannel(), applySubmitRequest.getOrderNo(), applySubmitRequest.getAuthData());

            /*更新认证订单号进id对应表*/
            thirdIdModel.setCAppId(MapUtils.getString(apiResult, "cAppId"));
            thirdCommonLogic.insertOrUpdateIdMapping(applySubmitRequest.getOrderNo(), apiRequestModel.getChannel(), thirdIdModel);
            /*更新推送流水*/
            ApiResponseModel<ApplySubmitResponse> apiResponseModel = new ApiResponseModel<>(Boolean.TRUE, 0, "", new ApplySubmitResponse(ApplySubmitStatusEnum.SUCCESS.getStatus(), ""));
            applySubmitLogic.updateApplyPushFlow(flowId, apiResponseModel);
            return apiResponseModel;
        } catch (CashChannelException e) {
            log.error(e.getMessage(), e);
            return new ApiResponseModel<>(false, -1, e.getMessage(), new ApplySubmitResponse(e.getCode(), e.getErrMessage()));
        }catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            return new ApiResponseModel<>(false, -1, ex.getMessage(), new ApplySubmitResponse("500", ex.getMessage()));
        }
    }

    private OrderInfoModel createOrderInfoModel(UserInfoModel userInfoModel, ApplySubmitRequest applySubmitRequest, String frontPath, String backPath) throws CashChannelException {
        OrderInfoModel orderInfoModel = new OrderInfoModel();
        BeanUtils.copyProperties(userInfoModel, orderInfoModel);
        orderInfoModel.setcLatitude(applySubmitRequest.getLatitude());
        orderInfoModel.setcLongitude(applySubmitRequest.getLongitude());
        orderInfoModel.setcClientIp(applySubmitRequest.getIp());
        orderInfoModel.setcMacAddr(applySubmitRequest.getMacAddr());
        orderInfoModel.setcImei(applySubmitRequest.getImei());
        orderInfoModel.setcOsType(applySubmitRequest.getOsType());
        orderInfoModel.setIsFinal(1);
        FileInfoModel frontImage = new FileInfoModel("1020", frontPath.substring(frontPath.lastIndexOf("/")+1), frontPath);
        FileInfoModel backImage = new FileInfoModel("1021", backPath.substring(backPath.lastIndexOf("/")+1), backPath);
        orderInfoModel.addFileInfoModel(frontImage);
        orderInfoModel.addFileInfoModel(backImage);
        return orderInfoModel;
    }

    private UserInfoModel createUserInfoModelByRequest(ApplySubmitRequest applySubmitRequest) throws CashChannelException {
        /*填充userInfo基本信息*/
        UserInfoModel userInfoModel = new UserInfoModel();
        userInfoModel.setcName(applySubmitRequest.getName());
        userInfoModel.setcIdno(applySubmitRequest.getIdNo());
        userInfoModel.setcMobile(applySubmitRequest.getMobile());

        userInfoModel.setcEmail(StringUtils.isEmpty(applySubmitRequest.getBaseInfo().getEmail())?
                EmailUtils.getEmailByPhone(applySubmitRequest.getMobile()) :applySubmitRequest.getBaseInfo().getEmail());
        userInfoModel.setcIdnoValid(getIdNoValid(applySubmitRequest.getIdInfo().getVerifiedIdValidBegin(), applySubmitRequest.getIdInfo().getVerifiedIdValidEnd()));
        userInfoModel.setcMarriage(applySubmitRequest.getBaseInfo().getMarriage());
        userInfoModel.setcScholarship(applySubmitRequest.getBaseInfo().getDegree());
        userInfoModel.setcChildrenNumber(applySubmitRequest.getBaseInfo().getChildName());

        /*填充地址信息*/
        insertAddressDataToUserInfoModel(userInfoModel, applySubmitRequest);

        /*填充工作信息*/
        insertJobDataToUserInfoModel(userInfoModel, applySubmitRequest);

        /*填充联系人信息*/
        insertContactDataToUserInfoModel(userInfoModel, applySubmitRequest);
        return userInfoModel;
    }

    private void insertContactDataToUserInfoModel(UserInfoModel userInfoModel, ApplySubmitRequest applySubmitRequest) {
        UserContactModel userContactModel = new UserContactModel();
        userContactModel.setcName1(applySubmitRequest.getContactInfo().getName1());
        userContactModel.setcMobile1(applySubmitRequest.getContactInfo().getMobile1());
        userContactModel.setcRelation1(applySubmitRequest.getContactInfo().getRelation1());
        userContactModel.setcName2(applySubmitRequest.getContactInfo().getName2());
        userContactModel.setcMobile2(applySubmitRequest.getContactInfo().getMobile2());
        userContactModel.setcRelation2(applySubmitRequest.getContactInfo().getRelation2());
        userInfoModel.setUserContactModel(userContactModel);
    }

    private void insertJobDataToUserInfoModel(UserInfoModel userInfoModel, ApplySubmitRequest applySubmitRequest) {
        UserJobModel userJobModel = new UserJobModel();
        userJobModel.setcAgeOfJob(applySubmitRequest.getBaseInfo().getAgeOfJob());
        userJobModel.setcCpnyAddrCode(applySubmitRequest.getBaseInfo().getCompanyCityCode());
        userJobModel.setcCpnyArea(applySubmitRequest.getBaseInfo().getCompanyArea());
        userJobModel.setcCpnyCity(applySubmitRequest.getBaseInfo().getCompanyCity());
        userJobModel.setcCpnyDistinct(applySubmitRequest.getBaseInfo().getCompanyDistrict());
        userJobModel.setcCpnyProvince(applySubmitRequest.getBaseInfo().getCompanyProvince());
        userJobModel.setcCpnyDetailAddress(applySubmitRequest.getBaseInfo().getCompanyDetailAddress());
        userJobModel.setcCpnyName(applySubmitRequest.getBaseInfo().getCompanyName());
        userJobModel.setcCpnyTel(applySubmitRequest.getBaseInfo().getCompanyTel());
        userJobModel.setcJobCityCode(applySubmitRequest.getBaseInfo().getCompanyCityCode());
        userJobModel.setcJobDistinctCode(applySubmitRequest.getBaseInfo().getCompanyDistrictCode());
        userJobModel.setcJobProvinceCode(applySubmitRequest.getBaseInfo().getCompanyProvinceCode());
        userJobModel.setcJobType(applySubmitRequest.getBaseInfo().getJobType());
        userJobModel.setcRangeOfSalary(applySubmitRequest.getBaseInfo().getMonthlyIncome());
        userInfoModel.setUserJobModel(userJobModel);
    }

    private void insertAddressDataToUserInfoModel(UserInfoModel userInfoModel, ApplySubmitRequest applySubmitRequest) {
        UserAddressModel userAddressModel = new UserAddressModel();
        userAddressModel.setcAddrCode(applySubmitRequest.getBaseInfo().getHouseDistrictCode());
        userAddressModel.setcCity(applySubmitRequest.getBaseInfo().getHouseCity());
        userAddressModel.setcDistinct(applySubmitRequest.getBaseInfo().getHouseDistrict());
        userAddressModel.setcProvince(applySubmitRequest.getBaseInfo().getHouseProvince());
        userAddressModel.setcCityCode(applySubmitRequest.getBaseInfo().getHouseCityCode());
        userAddressModel.setcDistinctCode(applySubmitRequest.getBaseInfo().getHouseDistrictCode());
        userAddressModel.setcProvinceCode(applySubmitRequest.getBaseInfo().getHouseProvinceCode());
        userAddressModel.setcDetailAddress(applySubmitRequest.getBaseInfo().getHouseDetailAddress());
        userAddressModel.setcHouseType(applySubmitRequest.getBaseInfo().getHouseType());
        userAddressModel.setcRegistryCity(applySubmitRequest.getIdInfo().getVerifiedIdAddress());
        userInfoModel.setUserAddressModel(userAddressModel);
    }

    private String getIdNoValid(String verifiedIdValidBegin, String verifiedIdValidEnd) throws CashChannelException {
        verifiedDateFormat(verifiedIdValidBegin);
        verifiedDateFormat(verifiedIdValidEnd);
        checkValid(verifiedIdValidBegin, verifiedIdValidEnd);
        return verifiedIdValidBegin + "-" + verifiedIdValidEnd;
    }

    private String verifiedDateFormat(String verifiedIdValidBegin) throws CashChannelException {
        try {
            Date date = DateUtils.parseDate(verifiedIdValidBegin.trim(), "yyyy-MM-dd","yyyyMMdd", "yyyy.MM.dd");
            return DateFormatUtils.format(date, "yyyy.MM.dd");
        } catch (ParseException e) {
            throw new CashChannelException("日期格式转换失败");
        }
    }

    private void checkValid(String verifiedIdValidBegin, String verifiedIdValidEnd) throws CashChannelException {
        try{
            if (DateUtils.parseDate(verifiedIdValidBegin, "yyyyMMdd", "yyyy.MM.dd","yyyy-MM-dd").after(new Date())) {
                throw new CashChannelException("身份证不在有效期");
            }
            if (!"长期".equalsIgnoreCase(verifiedIdValidEnd)) {
                if (DateUtils.parseDate(verifiedIdValidEnd, "yyyyMMdd", "yyyy.MM.dd","yyyy-MM-dd").before(new Date())) {
                    throw new CashChannelException("身份证不在有效期");
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            throw new CashChannelException(ex.getMessage());
        }
    }

    @Override
    public ApiResponseModel<ApplySubmitResponse> doFirstPush(ApiRequestModel apiRequestModel) {
        return null;
    }

    @Override
    public ApiResponseModel<ApplySubmitResponse> doSecondPush(ApiRequestModel apiRequestModel) {
        return null;
    }
}
